package com.atguigu.spzx.service.user.service.impl;

import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.RandomUtil;
import com.atguigu.commom.utils.IpUtil;
import com.atguigu.commom.utils.RegexValidateUtils;
import com.atguigu.spzx.service.user.mapper.UserInfoMapper;
import com.atguigu.spzx.service.user.service.UserAddressService;
import com.atguigu.spzx.service.user.service.UserInfoService;
import com.atguigu.spzx.common.handler.exception.SpzxException;
import com.atguigu.spzx.common.handler.interceptor.SpzxAuthInterceptor;
import com.atguigu.spzx.model.common.ResultCodeEnum;
import com.atguigu.spzx.model.dto.h5.UserInfoDto;
import com.atguigu.spzx.model.entity.h5.UserInfo;
import com.atguigu.spzx.model.vo.h5.UserInfoVo;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import java.util.Date;
import java.util.concurrent.TimeUnit;

/**
 * title:
 * author: zgl
 * date: 2024/1/16
 * description：
 */
@Service
public class UserInfoServiceImpl extends ServiceImpl<UserInfoMapper, UserInfo> implements UserInfoService {
    @Resource
    private StringRedisTemplate stringRedisTemplate;

    @Resource
    private RedisTemplate redisTemplate;

    @Resource
    private UserAddressService userAddressService;


    @Override
    public void register(UserInfoDto userInfoDto) {
        //校验参数
        String code = userInfoDto.getCode();
        String password = userInfoDto.getPassword();
        String username = userInfoDto.getUsername();
        String nickName = userInfoDto.getNickName();
        if (StringUtils.isEmpty(code) || StringUtils.isEmpty(password) || StringUtils.isEmpty(username) || StringUtils.isEmpty(nickName)
                || !RegexValidateUtils.checkCellphone(username)) {
            throw new SpzxException(ResultCodeEnum.COMMIT_PARAM_ERROR);
        }
        String redisCode = stringRedisTemplate.opsForValue().get("spzx:code:register" + username);
        if (StringUtils.isEmpty(redisCode) || !code.equals(redisCode)) {
            throw new SpzxException(ResultCodeEnum.COMMIT_CODE_ERROR);
        }
        long count = this.count(Wrappers.lambdaQuery(UserInfo.class).eq(UserInfo::getUsername, username));
        if (count > 0) {
            throw new SpzxException(ResultCodeEnum.PHONE_REGISTER_EXISTS);
        }
        //加密
        UserInfo userInfo = new UserInfo();
        BeanUtils.copyProperties(userInfoDto, userInfo);
        String salt = RandomUtil.randomString(6);
        userInfo.setSalt(salt);
        String newPassword = DigestUtils.md5DigestAsHex((DigestUtils.md5DigestAsHex(userInfo.getPassword().getBytes()) + salt).getBytes());
        userInfo.setPassword(newPassword);
        userInfo.setStatus(1);
        userInfo.setAvatar("http://192.168.144.100:9000/spzx-bucket/avatar/2023-12/29/cb716f.jpg");
        this.save(userInfo);
        //清空数据
        stringRedisTemplate.delete("spzx:code:register" + username);
    }

    @Override
    public String login(UserInfo userInfo) {
        String username = userInfo.getUsername();
        String password = userInfo.getPassword();
        if (StringUtils.isEmpty(username) || StringUtils.isEmpty(password) || !RegexValidateUtils.checkCellphone(username)) {
            throw new SpzxException(ResultCodeEnum.LOGIN_PARAM_ERROR);
        }
        UserInfo dbUserInfo = baseMapper.selectOne(Wrappers.lambdaQuery(UserInfo.class).eq(UserInfo::getUsername, username));
        if (dbUserInfo == null || dbUserInfo.getStatus() != 1) {
            throw new SpzxException(ResultCodeEnum.Login_USERNAME_ERROR);
        }
        String newPassword = DigestUtils.md5DigestAsHex((DigestUtils.md5DigestAsHex(userInfo.getPassword().getBytes()) + dbUserInfo.getSalt()).getBytes());
        String dbPassword = dbUserInfo.getPassword();
        if (!newPassword.equals(dbPassword)) {
            throw new SpzxException(ResultCodeEnum.Login_PASSWORD_ERROR);
        }
        //更新ip和登录时间
        ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = requestAttributes.getRequest();
        String ipAddress = IpUtil.getIpAddress(request);
        dbUserInfo.setLastLoginIp(ipAddress);
        dbUserInfo.setLastLoginTime(new Date());
        updateLoginInfo(dbUserInfo);
        dbUserInfo.setPassword("");
        dbUserInfo.setSalt("");
        String token = IdUtil.createSnowflake(1, 1).nextIdStr();
        redisTemplate.opsForValue().set("spzx:user:login" + token, dbUserInfo, 7, TimeUnit.DAYS);
        return token;
    }


    @Override
    public UserInfoVo getUserInfo(String token) {
//        UserInfo userInfo =(UserInfo) redisTemplate.opsForValue().get("spzx:user:login" + token);
//        if(userInfo == null){
//            throw new SpzxException(ResultCodeEnum.LOGIN_STATUS_ERROR);
//        }
        UserInfo userInfo = SpzxAuthInterceptor.threadLocal.get();
        UserInfoVo userInfoVo = new UserInfoVo();
        userInfoVo.setNickName(userInfo.getNickName());
        userInfoVo.setAvatar(userInfo.getAvatar());
        return userInfoVo;
    }


    @Override
    public void updateLoginInfo(UserInfo userInfo) {
        this.updateById(userInfo);
    }

    @Override
    public void logout(String token) {
        redisTemplate.delete("spzx:user:login" + token);
    }


}
